package com.ruoyi.web.controller.api;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.Collections;
import java.util.Date;
import java.util.UUID;
import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class RedisDistributedLock {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    /**
     * 尝试获取锁
     * @param lockKey 锁的key
     * @param requestId 请求ID（用于释放锁时验证）
     * @param expireSeconds 锁过期时间（秒）
     * @return 是否获取成功
     */
    public boolean tryLock(String lockKey, String requestId, int expireSeconds) {
        try {
            // 使用setIfAbsent，相当于Redis的 SET key value NX EX seconds
            Boolean result = redisTemplate.opsForValue().setIfAbsent(
                    lockKey, requestId, Duration.ofSeconds(expireSeconds));

            boolean success = Boolean.TRUE.equals(result);
            log.debug("尝试获取锁: {}, 请求ID: {}, 结果: {}", lockKey, requestId, success);
            return success;

        } catch (Exception e) {
            log.error("获取锁异常: {}", lockKey, e);
            return false;
        }
    }

    /**
     * 释放锁（检查是否是当前请求持有的锁）
     * @param lockKey 锁的key
     * @param requestId 请求ID
     * @return 是否释放成功
     */
    public boolean releaseLock(String lockKey, String requestId) {
        try {
            String currentValue = redisTemplate.opsForValue().get(lockKey);
            // 只有当前请求持有的锁才能释放
            if (requestId.equals(currentValue)) {
                Boolean deleted = redisTemplate.delete(lockKey);
                log.debug("释放锁: {}, 请求ID: {}, 结果: {}", lockKey, requestId, deleted);
                return Boolean.TRUE.equals(deleted);
            } else {
                log.warn("尝试释放非本人持有的锁: {}, 当前值: {}, 请求ID: {}",
                        lockKey, currentValue, requestId);
                return false;
            }
        } catch (Exception e) {
            log.error("释放锁异常: {}", lockKey, e);
            return false;
        }
    }

    /**
     * 强制释放锁（慎用，一般用于清理过期锁）
     * @param lockKey 锁的key
     * @return 是否删除成功
     */
    public boolean forceReleaseLock(String lockKey) {
        try {
            Boolean deleted = redisTemplate.delete(lockKey);
            log.info("强制释放锁: {}, 结果: {}", lockKey, deleted);
            return Boolean.TRUE.equals(deleted);
        } catch (Exception e) {
            log.error("强制释放锁异常: {}", lockKey, e);
            return false;
        }
    }

    /**
     * 检查锁是否存在
     * @param lockKey 锁的key
     * @return 锁是否存在
     */
    public boolean isLocked(String lockKey) {
        try {
            return Boolean.TRUE.equals(redisTemplate.hasKey(lockKey));
        } catch (Exception e) {
            log.error("检查锁状态异常: {}", lockKey, e);
            return false;
        }
    }
}